/**
 * Universidad del Valle de Guatemala
 * CC2003 Algoritmos y Estructuras de Datos
 * Proyecto 1: Inérprete de LISP --> Lambda LISP
 * Integrantes:
 *      Julio Chicas, José García, Ernesto Rodríguez, Karen Tojín
 **/

/**
 * Descripción: Realización de las evaluaciones del input ingresado por el usuario
 **/

import java.util.ArrayList;

public class Evaluaciones {

    public static String EvaluarInput(String instruction) throws ExceptionErrorInStatement {

        //int numLinea=0;

        boolean correcto = false;
        int cont = 0;
        String newString = "";
        char car = ' ';
        for (int i = 0; (i < instruction.length() || !(correcto && cont == 0)); i++) {
            car = instruction.charAt(i);
            if (car == '(') {
                correcto = true;
                newString += " ( ";
                cont++;
            }
            if (car == ')') {
                newString += " ) ";
                cont--;
            }
            if (cont != 0 && car != ')' && car != '(') {
                newString += instruction.charAt(i);
            }
        }

        if (correcto && cont == 0) {
            return newString;
        } else {
            throw new ExceptionErrorInStatement();
        }
    }

    public static ArrayList<String> EvaluarOperandos(String prevList) throws ExceptionErrorInStatement {
        ArrayList<String> operandos = new ArrayList<String>(0);
        String temp = "";
        String op = "";
        boolean addable = true;
        boolean prerun = true;
        String preOp;
        for (int a = 0; a < prevList.length(); a++) {
            prerun = true;
            try {
                if (prevList.substring(a, a + 2).equals("- ") || prevList.substring(a, a + 2).equals("-(")) {
                    if (!backSearch(temp)) {
                        throw new ExceptionErrorInStatement();
                    }
                    operandos.add("-");
                    addable = false;
                }
                preOp = prevList.substring(a, a + 3);
                if ((preOp.equals("if ")) || (preOp.equals("or ")) || (preOp.equals("if(")) || (preOp.equals("or("))) {
                    if (backSearch(temp)) {
                        operandos.add(preOp.substring(0, 2));
                        addable = false;
                        a++;
                    }
                }
                preOp = prevList.substring(a, a + 3);
                if ((preOp.equals("<= ")) || (preOp.equals(">= ")) || (preOp.equals("/= ")) || (preOp.equals("<=(")) || (preOp.equals(">=(")) || (preOp.equals("/=("))) {
                    if (backSearch(temp)) {
                        operandos.add(preOp.substring(0, 2));
                        addable = false;
                        a++;
                        prerun = false;
                    }
                }
                preOp = prevList.substring(a, a + 4);
                if ((preOp.equals("and ")) || (preOp.equals("and("))) {
                    if (backSearch(temp)) {
                        operandos.add(preOp.substring(0, 3));
                        addable = false;
                        a++;
                        a++;
                    }
                }
                if ((preOp.equals("not ")) || (preOp.equals("not("))) {
                    if (backSearch(temp)) {
                        operandos.add(preOp.substring(0, 3));
                        temp = temp + " 0 ";
                        addable = false;
                        a++;
                        a++;
                    }
                }
                preOp = prevList.substring(a, a + 5);
                if ((preOp.equals("cond ")) || (preOp.equals("cond("))) {
                    if (backSearch(temp)) {
                        operandos.add(preOp.substring(0, 4));
                        addable = false;
                        a++;
                        a++;
                        a++;
                    }
                }
            } catch (IndexOutOfBoundsException e) {
            }
            op = prevList.substring(a, a + 1);
            if ((op.equals("+") || op.equals("*") || op.equals("/") || op.equals("%") || op.equals("=") || op.equals("<") || op.equals(">")) && prerun) {
                // <editor-fold defaultstate="collapsed" desc="comment">
                if (!backSearch(temp)) {
                    throw new ExceptionErrorInStatement();
                }
                operandos.add(op);// </editor-fold>

            } else {
                if (addable) {
                    temp = temp + op;
                } else {
                    addable = true;
                }
            }
        }
        operandos.add(EvaluarInput(temp));
        return operandos;
    }

    private static boolean backSearch(String s) {
        boolean correct = false;
        boolean nDone = true;
        int cont = s.length();
        char r;
        while (nDone && cont > 0) {
            cont--;
            r = s.charAt(cont);
            if (r != ' ') {
                nDone = false;
                if (r == '(') {
                    correct = true;
                }
            }
        }

        return correct;
    }
}
